﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using  PI_CS_Library.Virtual_Network_Information_Model;
using PI_CS_Tools;

namespace  PI_CS_Library.PicsNetwork_Information_Model
{
    public class PicsVirtualLink : Link
    {
        new Identification _id;
        double _weightSum;
        Dictionary<int, PicsLink> _picsLinkList;
        PicsMatrix _srcMatrix;
        PicsMatrix _sinkMatrix;
        int _linkId;
        int _vnId;
        LinkParameters _requirements;

        public PicsVirtualLink(int _vnId, LinkParameters _linkRequirements)
            : base(_linkRequirements.Capacity)
        {
            _id = new Identification("Virtual Link");
            
            this._vnId = _vnId;
            
            _picsLinkList = new Dictionary<int, PicsLink>();
            
            _weightSum = 0;

            _requirements = _linkRequirements;

            _srcMatrix = null;
            _sinkMatrix = null;

        }

        public PicsVirtualLink(int _vnId, double _weightSum, LinkParameters _linkRequirements)
            : base(_linkRequirements.Capacity)
        {
            _id = new Identification("Virtual Link");
            
            this._vnId = _vnId;
            
            _picsLinkList = new Dictionary<int, PicsLink>();
            
            this._weightSum = _weightSum;

            _requirements = _linkRequirements;

            _srcMatrix = null;
            _sinkMatrix = null;
        }
     
        // Copy constructor

        public PicsVirtualLink(PicsVirtualLink _oldVirtualLink)
            : base(_oldVirtualLink.Parameters)
        {
            _picsLinkList = new Dictionary<int, PicsLink>(_oldVirtualLink.PicsLinkList);

            _linkConnectionsList = new Dictionary<int, LinkConnection>(_oldVirtualLink._linkConnectionsList);

            _weightSum = _oldVirtualLink._weightSum;

            _requirements = new LinkParameters(_oldVirtualLink._requirements);

            _id = _oldVirtualLink._id;

            _vnId = _oldVirtualLink._vnId;

            _linkId = _oldVirtualLink._linkId;

            _srcMatrix = _oldVirtualLink._srcMatrix;

            _sinkMatrix = _oldVirtualLink._sinkMatrix;

        }

 
        public void AddPicsLink(PicsLink _newLink, PicsMatrix _newNode)
        {
            // set the new sink/src matrix for virtual link

            if(_picsLinkList.Count==0)
            {
                _srcMatrix = _newLink.SrcMatrix;
                _sinkMatrix = _newLink.SinkMatrix;
            }

            else
            {
                if (_newLink.SrcMatrix == _newNode)
                    _srcMatrix = _newNode;

                else if (_newLink.SinkMatrix == _newNode)
                    _sinkMatrix = _newNode;
            } 

            _picsLinkList.Add(_newLink.Id.Number,_newLink);

            _weightSum += _newLink.VnWeightList[_vnId] + _newNode.VnWeightList[_vnId];

            _parameters.Delay += _newLink.Parameters.Delay + _newNode.Parameters.Delay;

            if (_parameters.ErrorRate == 0)
                _parameters.ErrorRate = _newLink.Parameters.ErrorRate;
            else if (_newLink.Parameters.ErrorRate != 0)
                _parameters.ErrorRate = 1 - ((1 - _parameters.ErrorRate) * (1 - _newLink.Parameters.ErrorRate));

        }

        new public Identification Id
        {
            get { return _id; }
            set { _id = value; }
        }

        new public PicsMatrix SrcMatrix
        {
            get { return _srcMatrix; }
            set { _srcMatrix = value; }
        }

        new public PicsMatrix SinkMatrix
        {
            get { return _sinkMatrix; }
            set { _sinkMatrix = value; }
        }

        public int LinkId
        {
            get { return _linkId; }
            set { _linkId = value; }
        }

        public int vnId
        {
            get { return _vnId; }
            set { _vnId = value; }
        }

        public double WeightSum
        {
            get { return this._weightSum; }
            set { this._weightSum = value; }
        }

        new public LinkParameters Parameters
        {
            get { return _parameters; }
            set { _parameters = value; }
        }

        public LinkParameters Requirements
        {
            get { return _requirements; }
            set { _requirements = value; }
        }

        public Dictionary<int, PicsLink> PicsLinkList
        {
            get { return _picsLinkList; }
            set { _picsLinkList = value; }
        }

        public override string ToString()
        {
            return _id.Description;
        }
    }
}
